import React, { useState, useRef, FC, useEffect } from 'react'
import { WriterWrapper } from './style'
function debounce(func, wait) {
  let timeout
  return function () {
    const context = this
    const args = arguments
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      func.apply(context, args)
    }, wait)
  }
}

const Typewriter = ({ value, speed = 100, onClick, style }) => {
  // 显示的文字
  const [displayText, setDisplayText] = useState('')
  // 显示到的索引
  const [index, setIndex] = useState(0)
  // 打字方向
  const [flag, setFlag] = useState(true)

  // 定时器
  const timer = useRef(null)

  useEffect(() => {
    if (index <= 0 && !flag) {
      setFlag(true)
    }
    if (index >= value.length && flag) {
      setFlag(false)
    }
  }, [value, speed, index])

  useEffect(() => {
    const speedMap = {
      0: speed * 2,
      [value.length]: speed * 4,
    }
    timer.current = setTimeout(() => {
      if (flag) {
        setDisplayText((prev) => prev + (value[index] ?? ''))
        setIndex((prev) => prev + 1)
      } else {
        setDisplayText((prev) => prev.substring(0, prev.length - 1))
        setIndex((prev) => prev - 1)
      }
    }, speedMap[index] || speed)

    return () => {
      if (timer.current) {
        clearTimeout(timer.current)
        timer.current = null
      }
    }
  }, [value, speed, flag, index])

  const handleClick = debounce(() => {
    setFlag(false)
    // 用于设置文字
    onClick?.()
  }, speed)

  return (
    <>
      <WriterWrapper>
        <div className={'typewriter'} onClick={handleClick} style={style}>
          {displayText}
        </div>
      </WriterWrapper>
    </>
  )
}
export default function Writer() {
  const list = [
    '白日地中出，黄河天外来。',
    '帐底吹笙香吐麝，更无一点尘随马。',
    '青衫匹马万人呼，幕府当年急急符。',
    '奇文共欣赏，疑义相与析。',
    '一生傲岸苦不谐，恩疏媒劳志多乖。',
  ]
  const [value, setValue] = useState('红酥手，黄縢酒，满城春色宫墙柳。')
  const handleClick = () => {
    const res = list.sort((a, b) => Math.random() - 0.5)[0]
    setValue(res)
  }
  return <Typewriter value={value} onClick={handleClick} />
}
